from BugRanker import BugRanker
from GrammarFuzzer import GrammarFuzzer
import random
import string

"""
    In this file we show the functionality of our GrammarFuzzer.
    Like in TestCase1, we have a method named "remove_html_markup" and an oracle named "remove_html_oracle" 
    which checks the output of the test method.
    Instead of using a random fuzzer to generate inputs, we use a grammar-based fuzzer to create smarter inputs.

    We created a small grammar with the following rules:
    
    TAG_ -> <TAGNAME> | <TAGNAME="TAGVALUE"> | <TAGNAME='TAGVALUE'>
    TAGNAME -> STRING
    TAGVALUE' -> STRING
    SNIPPET -> STRING TAG_ STRING TAG_ STRING
    STRING -> all possible lower case chars | all possible punctuation 
        | all possible lower case chars STRING | all possible punctuation STRING
    
    The initial point is SNIPPET.
"""


def remove_html_oracle(inp,delivered):
    expected = remove_html_markup_bugless(inp)
    match = expected==delivered
    return 'PASS' if match else 'FAIL'

def remove_html_markup_bugless(s):
    tag = False
    quote = False
    out = ''
    for c in s:
        if c == '<' and not quote:
            tag = True
        elif c == '>' and not quote:
            tag = False
        elif (c == '"' or c == "'") and tag and not quote:
            quote = c
        elif c == quote:
            quote = False
        elif not tag:
            out += c
    return out

def remove_html_markup(s):
    tag = False
    out = ''
    for c in s:
        if c == '<':
            tag = not tag
        elif c == '>':
            tag = False
        elif not tag:
            out += c
    return out

def remove_single_char(s):
    index = int(random.random() * (len(s)-1))
    return s[:index]+s[index+1:]


def main():
    gfuzzer = GrammarFuzzer()
    # gfuzzer = GrammarFuzzer(equalizeCoverage=True) # uncomment to enable coverage-aware mode (slower)
    gfuzzer.addAnomalyMethod(remove_single_char)
    gfuzzer.setAnomalyProperty(0.1)
    gfuzzer.addProduction('TAG_','<TAGNAME>')
    gfuzzer.addProduction('TAG_','<TAGNAME="TAGVALUE">')
    gfuzzer.addProduction('TAG_',"<TAGNAME='TAGVALUE'>")
    gfuzzer.addProduction('TAGNAME','STRING')
    chars = string.lowercase+string.punctuation
    for c in chars:
        gfuzzer.addProduction('STRING', c)
        gfuzzer.addProduction('STRING', c+'STRING')
    gfuzzer.addProduction('TAGVALUE','STRING')
    gfuzzer.addProduction('SNIPPET', 'STRING TAG_ STRING TAG_ STRING')
    gfuzzer.setStartTerminal('SNIPPET')
    
    bugRanker = BugRanker(remove_html_markup, remove_html_oracle)
    bugRanker.setFuzzer(gfuzzer)
    bugRanker.generateChains(10)
    bugRanker.printBugList()
    # bugRanker.dumpBugList('testCase2.txt') # optionally you can store the results in a text file

if __name__ == '__main__':
    main()